package com.avic.gateway.filter;

import com.avic.gateway.common.constant.GatewayConstant;
import com.avic.gateway.common.util.Base64Util;
import com.avic.gateway.common.util.ex.BizErrorCode;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;

import java.util.concurrent.TimeUnit;

/**
 * 登入创建Token过滤器
 *
 * @author: huangsheng
 * @date: 2018/8/24
 */
@Slf4j
public class TokenValidatePreFilter extends AbstractZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 2;
    }

    @Override
    public boolean shouldFilter() {
        return shouldFilter(TokenValidatePreFilter.class.getSimpleName());
    }

    @Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        try {
            String managementToken = requestContext.getRequest().getHeader(GatewayConstant.MANAGEMENT_TOKEN_NAME);

            if (StringUtils.isBlank(managementToken)) {
                // token为空，没有访问权限
                return blockRequest(requestContext, BizErrorCode.MANAGEMENT_TOKEN_ERROR, 403);
            }
            String userId;
            try {
                userId = Base64Util.decode(managementToken).split(LoginCreateTokenPostFilter.TOKEN_PRE)[0];
                if (StringUtils.isBlank(userId)) {
                    throw new RuntimeException();
                }
            } catch (Exception e) {
                log.warn("token {} decrypt error {}", managementToken, e.getMessage());
                return blockRequest(requestContext, BizErrorCode.MANAGEMENT_TOKEN_ERROR, 403);
            }
            log.info("解析出UserID{}", userId);
            Object redisTokenObj = redisTemplate.opsForValue().get(GatewayConstant.REDIS_MANAGEMENT_TOKEN_SPACE + userId);
            if (null == redisTokenObj) {
                log.info("登入信息失效");
                return blockRequest(requestContext, BizErrorCode.MANAGEMENT_TOKEN_INVALID, 200);
            }
            if (StringUtils.isBlank(redisTokenObj.toString()) || !StringUtils.equals(redisTokenObj.toString(), managementToken)) {
                return blockRequest(requestContext, BizErrorCode.MANAGEMENT_TOKEN_INVALID, 200);
            }
            log.info("验证通过,将请求IP和UserId放到请求头中");
            // 重新设置过期时间
            redisTemplate.expire(GatewayConstant.REDIS_MANAGEMENT_TOKEN_SPACE + userId, 30, TimeUnit.MINUTES);
            requestContext.addZuulRequestHeader(GatewayConstant.HEADER_CURRENT_USER_ID_KEY, userId);
        } catch (Exception e) {
            log.error("TokenValidatePreFilter 内发生异常 {}", e.getMessage());
            return blockRequest(requestContext, BizErrorCode.SYSTEM_ERROR, 500);
        }
        return null;
    }
}
